<template>
  <!--edit SVG modal-->
  <ant-modal
    :title="'SVG编辑'"
    :getContainer="getPopupContainer"
    :visible="editSvgModalVisible"
    v-if="editSvgModalVisible"
    :modalWidth="1500"
    @cancelModal="changeEditModalStatus"
  >
    <div class="referenceDocument">
      <span>
        <a-popconfirm :showCancel="false">
          <template #title>
            <div>
              1.新增属性使用格式:
              <span class="code">
                :svg属性名="prop_data.defaultAttr.自定义属性字段名.val"
              </span>
              例如:
              <span class="code">:fill1="prop_data.defaultAttr.key1.val"</span>
            </div>
          </template>
          帮助
        </a-popconfirm>
      </span>
      <span @click="gotoReference">svg参考文档>></span>
    </div>
    <div class="svgEdit">
      <div class="editLeft">
        <a-form :model="previewEditSvg" ref="editSvgForm">
          <a-form-item
            label="SVG源代码"
            name="template"
            :rules="[{ required: true, message: '请输入SVG代码' }]"
          >
            <a-textarea
              style="font-size: 18px"
              :autoSize="{ minRows: 25, maxRows: 25 }"
              v-model:value="updataEditSvg.template"
              placeholder="请输入svg格式代码"
            />
          </a-form-item>
        </a-form>
      </div>
      <a-divider style="height: 100%" type="vertical" />
      <div class="editRight">
        <div class="previewSvg" ref="previewSvg">
          <svg
            v-if="showPreviewSvg"
            version="1.1"
            xmlns="http://www.w3.org/2000/svg"
            xmlns:xlink="http://www.w3.org/1999/xlink"
            preserveAspectRatio="xMinYMin meet"
            class="previewCanvas"
          >
            <g
              style="cursor: pointer"
              :transform="
                'translate(' +
                updataEditSvg.svgPositionX +
                ',' +
                updataEditSvg.svgPositionY +
                ')'
              "
            >
              <register-components
                ref="registerComponents"
                :component_prop="updataEditSvg"
                :svgInfoData="[previewEditSvg]"
              />
            </g>
          </svg>
          <a-empty v-else :description="errDescription" />
        </div>
        <a-button
          style="margin-bottom: 10px"
          type="primary"
          ghost
          @click="upDataPreviewSvg"
        >
          更新
        </a-button>
        <a-collapse v-model:activeKey="attributeActiveKey">
          <a-collapse-panel key="attribute" header="属性设置">
            <div class="attribute">
              <a-form
                v-if="updataEditSvg?.defaultAttr"
                ref="attributeForm"
                :model="updataEditSvg"
              >
                <div
                  class="svgAttributeItem"
                  v-for="(item, key) in updataEditSvg.defaultAttr"
                  :key="key"
                >
                  <a-row>
                    <a-col :span="5">
                      <a-form-item
                        :name="['defaultAttr', key, 'title']"
                        label="名称"
                        :rules="{
                          required: true,
                          message: '输入名称',
                          trigger: 'change',
                        }"
                      >
                        <a-input
                          allowClear
                          :placeholder="item.title ? item.title : '请输入名称'"
                          v-model:value="item.title"
                        />
                      </a-form-item>
                    </a-col>
                    <a-col :span="6">
                      <a-form-item
                        label="字段"
                        :name="['defaultAttr', key, 'key']"
                        :rules="[
                          {
                            required: true,
                            message: '请输入字段!',
                            trigger: 'change',
                          },
                        ]"
                      >
                        <a-input
                          disabled
                          allowClear
                          onkeyup="value=value.replace(/[^a-zA-Z0-9_]/g,'');"
                          :placeholder="
                            key ? key : '请输入字段(英文数组下划线组合)'
                          "
                          v-model:value="item.key"
                          @change="changeAttributeKey($event, item)"
                        />
                      </a-form-item>
                    </a-col>
                    <a-col :span="6">
                      <a-form-item
                        label="类型"
                        :name="['defaultAttr', key, 'type']"
                        :rules="[
                          {
                            required: true,
                            message: '请选择属性',
                            trigger: 'change',
                          },
                        ]"
                      >
                        <a-select
                          v-model:value="item.type"
                          :getPopupContainer="
                            (triggerNode) => triggerNode.parentNode
                          "
                          :options="typeDict"
                        />
                      </a-form-item>
                    </a-col>
                    <a-col :span="6">
                      <a-form-item
                        label="属性"
                        :name="['defaultAttr', key, 'val']"
                        :rules="[
                          {
                            required: true,
                            message: '属性值',
                            trigger: 'change',
                          },
                        ]"
                      >
                        <a-input-number
                          v-if="item?.type == 'numberinputbox'"
                          v-model:value="item.val"
                        />
                        <a-input
                          v-else-if="
                            item?.type == 'colorinputbox' && isFullscreen
                          "
                          type="color"
                          v-model:value="item.val"
                        />
                        <color-picker
                          v-else-if="
                            item?.type == 'colorinputbox' && !isFullscreen
                          "
                          useType="pure"
                          v-model:pureColor="item.val"
                        />
                        <a-input
                          v-else-if="item?.type == 'textinputbox'"
                          :placeholder="`请输入${item.title}`"
                          v-model:value="item.val"
                        />
                        <a-input
                          v-else-if="item?.type == 'textareainputbox'"
                          :placeholder="`请输入${item.title}`"
                          type="textarea"
                          v-model:value="item.val"
                        />
                        <a-radio-group
                          v-model:value="item.val.selectval"
                          v-else-if="item?.type == 'radiogroup'"
                        >
                          <a-space>
                            <a-radio
                              v-for="ridioitem in item.val.ridiogroup"
                              :key="ridioitem.value"
                              :value="ridioitem.value"
                            >
                              {{ ridioitem.label }}
                            </a-radio>
                          </a-space>
                        </a-radio-group>
                        <a-select
                          style="width: 150px"
                          v-else-if="item?.type == 'select'"
                          :getPopupContainer="
                            (triggerNode) => triggerNode.parentNode
                          "
                          v-model:value="item.val.selectval"
                          :options="item.val.selectgroup"
                        />
                      </a-form-item>
                    </a-col>
                    <a-col :span="1">
                      <a-popconfirm
                        ok-text="删除"
                        cancel-text="取消"
                        @confirm="deleteAttribute(key)"
                      >
                        <template #title>
                          <div>
                            删除该属性前,应该先修改svg代码中关联的属性值
                          </div>
                          <div>
                            是否删除名称为
                            <span class="code">
                              {{
                                selectAttribute.title
                                  ? selectAttribute.title
                                  : 'null'
                              }}
                            </span>
                            ,字段为
                            <span class="code">
                              {{
                                selectAttribute.key ? selectAttribute.key : key
                              }}
                            </span>
                            的属性值？
                          </div>
                        </template>
                        <minus-circle-outlined
                          @click="clickAttribute(item)"
                          style="
                            font-size: 20px;
                            color: #f81d22;
                            line-height: 38px;
                          "
                        />
                      </a-popconfirm>
                    </a-col>
                  </a-row>
                </div>
              </a-form>
              <a-empty v-else description="暂无相关属性" />
            </div>
          </a-collapse-panel>
        </a-collapse>
        <a-button
          ghost
          type="primary"
          style="margin-top: 5px"
          @click="addAttribute"
        >
          <template #icon>
            <plus-outlined />
          </template>
          增加属性
        </a-button>
      </div>
    </div>
    <div class="footer">
      <a-button @click="changeEditModalStatus">关闭</a-button>
      <a-button type="primary" @click="updateComponents">保存</a-button>
    </div>
  </ant-modal>
</template>
<script>
import { updateComponent } from '@/network/api/index';
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons-vue';
import { message } from 'ant-design-vue';
import registerComponents from './registerComponents.vue';
import antModal from '@/common/antComponents/antModal.vue';

let inputInterval = null;
let inputCount = 1;

export default {
  inject: ['getScreenFullNode', 'getScreenStatus'],
  components: {
    PlusOutlined,
    registerComponents,
    MinusCircleOutlined,
    antModal,
  },
  props: ['editSvgModalVisible', 'updataEditSvg'],
  watch: {
    updataEditSvg: {
      deep: true,
      immediate: true,
      handler(val) {
        if (val && JSON.stringify(val) != '{}') {
          this.showPreviewSvg = true;
          this.previewEditSvg = JSON.parse(JSON.stringify(val));
          this.$nextTick(() => {
            const documentAttribute =
              document.getElementsByClassName('previewSvg')[0];
            Object.assign(val, {
              svgPositionX: documentAttribute.clientWidth / 2,
              svgPositionY: documentAttribute.clientHeight / 3,
            });
            this.previewEditSvg = JSON.parse(JSON.stringify(val));
          });
        }
      },
    },
  },
  data() {
    return {
      attributeActiveKey: ['attribute'],
      errDescription: '暂无渲染SVG组件', //错误描述
      showPreviewSvg: false,
      previewEditSvg: {}, //当前选中回显svg
      typeDict: [
        { value: 'colorinputbox', label: '颜色选择器' },
        { value: 'numberinputbox', label: '数字输入框' },
        { value: 'textinputbox', label: '文本输入框' },
        { value: 'select', label: '下拉选择框', disabled: true },
        { value: 'textareainputbox', label: '文本域' },
        { value: 'radiogroup', label: '单选框', disabled: true },
      ],
    };
  },
  computed: {
    getPopupContainer() {
      return this.getScreenFullNode();
    },
    isFullscreen() {
      return this.getScreenStatus();
    },
  },
  methods: {
    changeEditModalStatus() {
      this.$emit('changeEditModalStatus');
    },
    gotoReference() {
      window.open(
        'https://developer.mozilla.org/zh-CN/docs/Web/SVG/Element#svg_%E5%85%83%E7%B4%A0',
        '_blank'
      );
    },
    matchAttribute() {
      const updataEditSvg = this.updataEditSvg;
      const reg = new RegExp('prop_data.defaultAttr.[a-zA-Z0-9]{0,30}', 'g');
      let keyArr = [];
      let flage = true;
      updataEditSvg.template.match(reg)
        ? updataEditSvg.template.match(reg).forEach((item) => {
            keyArr.push(item.replace(/prop_data.defaultAttr./g, ''));
          })
        : '';
      if (keyArr) {
        for (let i = 0; i < keyArr.length; i++) {
          if (!updataEditSvg.defaultAttr[keyArr[i]]) {
            message.warning(`缺少属性字段:${keyArr[i]},请手动更新或者删除`);
            flage = false;
            break;
          } else {
            flage = true;
          }
        }
      }
      return flage;
    },
    upDataPreviewSvg() {
      if (this.matchAttribute()) {
        this.previewEditSvg = JSON.parse(JSON.stringify(this.updataEditSvg));
        this.$nextTick(() => {
          setTimeout(() => {
            this.$refs.registerComponents.createComponents();
          }, 0);
        });
      }
    },
    clickAttribute(item) {
      this.selectAttribute = item;
    },
    deleteAttribute(key) {
      this.upDataPreviewSvg();
      const template = this.updataEditSvg.template;
      if (template.indexOf(key) <= -1) {
        this.$nextTick(() => {
          setTimeout(() => {
            delete this.updataEditSvg.defaultAttr[key];
          }, 0);
        });
      } else {
        message.warning('该字段使用中,删除失败~');
      }
    },
    addAttribute() {
      const len = Object.keys(this.updataEditSvg.defaultAttr).length + 1;
      this.updataEditSvg.defaultAttr[`key${len}`]
        ? (this.updataEditSvg.defaultAttr[`key${len}_copy`] = {
            title: `属性${len}`,
            key: `key${len}_copy`,
            type: 'colorinputbox', //默认为颜色选择器
            val: `key${len}`,
          })
        : (this.updataEditSvg.defaultAttr[`key${len}`] = {
            title: `属性${len}`,
            key: `key${len}`,
            type: 'colorinputbox', //默认为颜色选择器
            val: `key${len}`,
          });
    },
    updateComponents() {
      this.$refs['editSvgForm']
        .validate()
        .then(() => {
          this.$refs['attributeForm']
            .validate()
            .then(() => {
              if (this.matchAttribute()) {
                let updataEditSvg = JSON.parse(
                  JSON.stringify(this.updataEditSvg)
                );
                updataEditSvg.defaultAttr = JSON.stringify(
                  updataEditSvg.defaultAttr
                );
                this.$httpRequest(updateComponent, updataEditSvg, 'post').then(
                  () => {
                    message.success('更改成功~');
                    this.changeEditModalStatus();
                    this.$emit('getLeftComponents');
                  }
                );
              }
            })
            .catch(() => {
              message.warning('请输入属性必填框');
            });
        })
        .catch(() => {
          message.warning('请输入svg代码');
        });
    },
    changeAttributeKey(e, val) {
      inputCount = 1;
      clearInterval(inputInterval);
      inputInterval = setInterval(() => {
        inputCount--;
        if (inputCount == 0) {
          this.matchAttributeKey(val);
          clearInterval(inputInterval);
        }
      }, 1500);
    },
    matchAttributeKey(val) {
      if (val) {
        let attributeArr = this.updataEditSvg.defaultAttr;
        for (let attributeKey in attributeArr) {
          if (
            val.id == attributeArr[attributeKey].id &&
            attributeKey != val.key
          ) {
            //添加新修改的字段属性
            attributeArr[val.key] = attributeArr[attributeKey];
            delete attributeArr[attributeKey];
            break;
          }
        }
      }
    },
  },
};
</script>
<style lang="less" scoped>
::-webkit-scrollbar {
  width: 6px;
  height: 5px;
}

::-webkit-scrollbar-track {
  border-radius: 10px;
  background-color: #f2f2f2;
}

::-webkit-scrollbar-thumb {
  border-radius: 10px;
  background-color: #9e9e9e;
}

.referenceDocument {
  text-align: right;
  color: #1890ff;

  span {
    margin: 10px;
  }
}

.referenceDocument:hover {
  cursor: pointer;
}

.svgEdit {
  display: flex;
  max-height: 620px;
  height: 600px;
  overflow: auto;
  width: 100%;
  // text-align: center;

  .editLeft {
    flex: 1;
    height: 100%;
  }

  .editRight {
    flex: 1.5;
    height: 100%;
    text-align: center;

    .previewSvg {
      border: 1px solid #d9d9d9;
      position: relative;
      overflow: hidden;
      height: 222px;
      margin-bottom: 10px;
      text-align: center;
      width: 100%;

      .previewCanvas {
        width: 100%;
        height: 100%;
      }
    }

    .attribute {
      margin: 15px auto;
      max-height: 360px;
      height: 250px;
      overflow: auto;

      .svgAttributeItem {
        text-align: center;
        margin: 10px;
      }
    }
  }
}

/deep/ .vc-color-wrap {
  width: 100%;
}

.footer {
  margin: 0 auto;
  text-align: center;

  .ant-btn {
    margin: 10px;
  }
}

.inputStyle {
  width: 110px;
}

.code {
  background: #282c34;
  color: #abb2bf;
  font-weight: bold;
  padding: 3px;
  border-radius: 3px;
}
</style>
